using Avalonia.Controls;
using Avalonia.Input.Platform;
using Avalonia.Platform.Storage;
using CommunityToolkit.Mvvm.Input;
using DesktopApp.Models;
using DesktopApp.ViewModels;
using DesktopApp.ViewModels.Services;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.ComponentModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text.Json;
using System.Threading.Tasks;
using System.Windows.Input;
using CommunityToolkit.Mvvm.ComponentModel;

namespace DesktopApp.ViewModels
{
    // Define a constant or static readonly field for the special template name
    public static class SpecialTemplateNames
    {
        public const string AllRules = "(所有规则)";
        public const string DefaultRules = "(默认规则)"; // If we want a separate default option
        public const string ImportedPrefix = "已导入: ";
        public const string NoTemplateFallback = "(无模板 - 默认规则)";
        public const string ErrorFallbackPrefix = "(错误 - ";
    }

    // Helper record for grouping
    public record RuleGroup(string GroupName, IEnumerable<RuleItemViewModel> Items);

    public partial class RulesViewModel : ViewModelBase
    {
        private readonly IRuleManagementService _ruleManagementService;
        private readonly IUIService _uiService; // For dialogs
        private readonly LogPanelViewModel _logPanelViewModel; // Inject LogPanelViewModel

        public ObservableCollection<RuleItemViewModel> Rules { get; } = new ObservableCollection<RuleItemViewModel>();
        public ObservableCollection<LogProcessingTemplate> Templates { get; } = new ObservableCollection<LogProcessingTemplate>();
        public ObservableCollection<RuleItemViewModel> SelectedRules { get; } = new ObservableCollection<RuleItemViewModel>();
        public ObservableCollection<RuleSet> RuleSets { get; } = new ObservableCollection<RuleSet>();

        private RuleItemViewModel? _selectedRule;
        public RuleItemViewModel? SelectedRule
        {
            get => _selectedRule;
            set
            {
                if (SetProperty(ref _selectedRule, value))
                {
                    // Update CanExecute for Edit/Delete commands when selection changes
                    (EditRuleCommand as RelayCommand<object?>)?.NotifyCanExecuteChanged();
                    (DeleteRuleCommand as RelayCommand<object?>)?.NotifyCanExecuteChanged();
                }
            }
        }

        private LogProcessingTemplate? _selectedTemplate;
        public LogProcessingTemplate? SelectedTemplate
        {
            get => _selectedTemplate;
            set
            {
                if (SetProperty(ref _selectedTemplate, value))
                {
                    // PropertyChanged will trigger loading in the ShellViewModel or directly here
                     _ = LoadTemplateAsync(_selectedTemplate); // Load when selection changes
                }
            }
        }

        private string _currentTemplateLabel = "(无模板)";
        public string CurrentTemplateLabel
        {
            get => _currentTemplateLabel;
            private set => SetProperty(ref _currentTemplateLabel, value);
        }
        
        // Commands related to Rules and Templates
        public ICommand EditRuleCommand { get; }
        public ICommand DeleteRuleCommand { get; }
        public ICommand AddRuleCommand { get; }
        public ICommand ExportTemplateCommand { get; }
        public ICommand DeleteTemplateCommand { get; }
        public ICommand CreateRuleFromSelectionCommand { get; }
        public ICommand CreateTemplateFromSelectionCommand { get; }
        public ICommand ImportTemplateCommand { get; }
        public ICommand ExportAllTemplatesCommand { get; }
        public ICommand ImportTemplatesFromFolderCommand { get; }

        // Grouped Rules for UI
        public IEnumerable<RuleGroup> GroupedRules => GenerateGroupedRules();

        // Event for statistics recalculation
        public event EventHandler? RulesChangedForStats;

        public RulesViewModel(IRuleManagementService ruleManagementService, IUIService uiService, LogPanelViewModel logPanelViewModel)
        {
            _ruleManagementService = ruleManagementService;
            _uiService = uiService;
            _logPanelViewModel = logPanelViewModel; // Store injected instance

            // Initialize Commands
            EditRuleCommand = new AsyncRelayCommand<object?>(EditRule, CanEditOrDeleteRule);
            DeleteRuleCommand = new AsyncRelayCommand<object?>(DeleteRule, CanEditOrDeleteRule);
            AddRuleCommand = new AsyncRelayCommand(AddRule);
            ExportTemplateCommand = new AsyncRelayCommand(ExportTemplateAsync, CanExportTemplate);
            DeleteTemplateCommand = new AsyncRelayCommand<object?>(DeleteSelectedTemplate, CanDeleteTemplate);
            CreateRuleFromSelectionCommand = new AsyncRelayCommand(CreateRuleFromSelection, CanCreateRuleFromSelection);
            CreateTemplateFromSelectionCommand = new AsyncRelayCommand(CreateTemplateFromSelectionAsync, CanCreateTemplateFromSelection);
            ImportTemplateCommand = new AsyncRelayCommand(ImportTemplateAsync);
            ExportAllTemplatesCommand = new AsyncRelayCommand(ExportAllTemplatesAsync);
            ImportTemplatesFromFolderCommand = new AsyncRelayCommand(ImportTemplatesFromFolderAsync);

            // Add the "All Rules" pseudo-template initially
            Templates.Add(new LogProcessingTemplate { Name = SpecialTemplateNames.AllRules });
            _selectedTemplate = Templates[0]; // Default selection to "All Rules"
            CurrentTemplateLabel = SpecialTemplateNames.AllRules;

            // Subscribe to collection changes for stats and grouping updates
            Rules.CollectionChanged += Rules_CollectionChanged;
            SelectedRules.CollectionChanged += SelectedRules_CollectionChanged;

            // Subscribe to LogPanelVm's event to update CanExecute
            _logPanelViewModel.SelectedOriginalLogTextChanged += LogPanelVm_SelectedOriginalLogTextChanged;

             // Load initial data (templates and potentially default rules)
             _ = LoadInitialDataAsync();
        }

        // --- Event Handlers for Rule Stats & Grouping ---
        private void Rules_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            if (e.OldItems != null)
            {
                foreach (RuleItemViewModel item in e.OldItems.OfType<RuleItemViewModel>())
                {
                    item.PropertyChanged -= Rule_PropertyChanged;
                    item.PropertyChanged -= RuleItem_IsSelectedChanged; // Unsubscribe from IsSelected changes
                }
            }
            if (e.NewItems != null)
            {
                foreach (RuleItemViewModel item in e.NewItems.OfType<RuleItemViewModel>())
                {
                    item.PropertyChanged += Rule_PropertyChanged;
                    item.PropertyChanged += RuleItem_IsSelectedChanged; // Subscribe to IsSelected changes
                    // Initialize SelectedRules based on initial IsSelected state?
                    if(item.IsSelected && !SelectedRules.Contains(item))
                    {
                        SelectedRules.Add(item);
                    }
                }
            }
            NotifyRulesChangedForStats(); // Notify stats need recalculation
            OnPropertyChanged(nameof(GroupedRules)); // Re-enable notification for grouping updates
        }

        private void SelectedRules_CollectionChanged(object? sender, NotifyCollectionChangedEventArgs e)
        {
            // Notify command that its CanExecute condition might have changed
            (CreateTemplateFromSelectionCommand as IAsyncRelayCommand)?.NotifyCanExecuteChanged();
            // Optional: Update single SelectedRule property if needed for other logic/bindings
            // OnPropertyChanged(nameof(SelectedRule)); // Not strictly necessary if only relying on SelectedRules
            OnPropertyChanged(nameof(GroupedRules)); // Re-enable notification for grouping updates
        }

        // Handler for individual RuleItemViewModel IsSelected changes
        private void RuleItem_IsSelectedChanged(object? sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(RuleItemViewModel.IsSelected) && sender is RuleItemViewModel changedItem)
            {
                if (changedItem.IsSelected)
                {
                    if (!SelectedRules.Contains(changedItem))
                    {
                        SelectedRules.Add(changedItem);
                    }
                }
                else
                {
                    if (SelectedRules.Contains(changedItem))
                    {
                        SelectedRules.Remove(changedItem);
                    }
                }
                // CreateTemplateFromSelectionCommand CanExecute is updated by SelectedRules.CollectionChanged handler
                // Debug.WriteLine($"[RulesViewModel] Rule '{changedItem.Name}' IsSelected changed to {changedItem.IsSelected}. SelectedRules count: {SelectedRules.Count}");
            }
        }

        private void Rule_PropertyChanged(object? sender, PropertyChangedEventArgs e)
        {
            if (e.PropertyName == nameof(RuleItemViewModel.IsEnabled) || e.PropertyName == nameof(RuleItemViewModel.Type))
            {
                NotifyRulesChangedForStats(); // Notify stats need recalculation
            }
            if (e.PropertyName == nameof(RuleItemViewModel.Type)) // Type change affects grouping
            {
                 OnPropertyChanged(nameof(GroupedRules));
            }
        }
        
        protected virtual void NotifyRulesChangedForStats()
        {
            RulesChangedForStats?.Invoke(this, EventArgs.Empty);
        }

        // Helper method to assign commands to a rule item VM
        private void AssignCommandsToRule(RuleItemViewModel rule)
        {
            rule.EditCommand = this.EditRuleCommand;
            rule.DeleteCommand = this.DeleteRuleCommand;
        }

        // --- Command Execution Methods (Moved and Adapted) ---
        private async Task AddRule()
        {
            var newRule = await _ruleManagementService.AddRuleAsync();
            if (newRule != null)
            {
                AssignCommandsToRule(newRule); // Assign commands
                newRule.PropertyChanged += Rule_PropertyChanged; 
                Rules.Add(newRule);
            }
        }

        private async Task EditRule(object? parameter)
        {
            var ruleToEdit = parameter as RuleItemViewModel ?? SelectedRule;
            if (ruleToEdit == null) return;

            // Store original type before editing
            var originalType = ruleToEdit.Type;
            var originalIsEnabled = ruleToEdit.IsEnabled;

            var updatedRuleData = await _ruleManagementService.EditRuleAsync(ruleToEdit);

            if (updatedRuleData != null)
            {
                // Apply changes (already done by service/dialog if instance is the same)
                // If EditRuleAsync returns a NEW instance or data DTO, apply here:
                // ruleToEdit.Name = updatedRuleData.Name;
                // ... etc ...
                Debug.WriteLine($"ViewModel: Rule '{ruleToEdit.Name}' updated.");

                 // Manually trigger PropertyChanged if the service modified the existing instance
                 // and didn't trigger notifications itself. Best if RuleItemViewModel handles this.
                 
                 // Trigger notifications if relevant properties changed
                 if (ruleToEdit.IsEnabled != originalIsEnabled)
                 {
                     Rule_PropertyChanged(ruleToEdit, new PropertyChangedEventArgs(nameof(RuleItemViewModel.IsEnabled)));
                 }
                  if (ruleToEdit.Type != originalType)
                 {
                     Rule_PropertyChanged(ruleToEdit, new PropertyChangedEventArgs(nameof(RuleItemViewModel.Type)));
                 }
            }
        }

        private async Task DeleteRule(object? parameter)
        {
            var ruleToDelete = parameter as RuleItemViewModel ?? SelectedRule;
            if (ruleToDelete == null) return;

            bool confirmed = await _ruleManagementService.ConfirmDeleteRuleAsync(ruleToDelete);

            if (confirmed && Rules.Contains(ruleToDelete))
            {
                 // CollectionChanged handles unsubscribe, stat updates, and grouping updates
                 Rules.Remove(ruleToDelete);
                 Debug.WriteLine($"ViewModel: Rule '{ruleToDelete.Name}' deleted.");
            }
        }

        private bool CanEditOrDeleteRule(object? parameter)
        {
            // Check parameter first, then SelectedRule
            return (parameter as RuleItemViewModel ?? SelectedRule) != null;
        }

        /// <summary>
        /// Moves a rule within the collection based on a source, a target, and a drop position.
        /// </summary>
        public void MoveRule(RuleItemViewModel sourceRule, RuleItemViewModel? targetRule, bool dropBefore)
        {
             if (sourceRule == null) return;

            int sourceIndex = Rules.IndexOf(sourceRule);
            if (sourceIndex < 0)
            {
                Debug.WriteLine($"MoveRule Error: Source rule '{sourceRule.Name}' not found in collection.");
                return; // Source rule not found
            }

            // Use ObservableCollection.Move for atomic operation if possible and better performance
             int targetIndex = -1;
             if (targetRule == null) {
                 targetIndex = Rules.Count -1; // Move to end if target is null
             } else {
                 targetIndex = Rules.IndexOf(targetRule);
                 if(targetIndex < 0) {
                     Debug.WriteLine($"MoveRule Warning: Target rule '{targetRule.Name}' not found. Moving to end.");
                     targetIndex = Rules.Count -1; // Move to end if target not found
                 } else if (!dropBefore) {
                     targetIndex++; // Adjust index to insert *after* the target
                 }
             }

             // Adjust target index if source is moved before its original position
             if (sourceIndex < targetIndex)
             {
                 targetIndex--;
             }
             
             // Clamp index just in case
             targetIndex = Math.Clamp(targetIndex, 0, Rules.Count - 1);


             if (sourceIndex != targetIndex) {
                  Debug.WriteLine($"Moving rule '{sourceRule.Name}' from {sourceIndex} to {targetIndex}");
                  Rules.Move(sourceIndex, targetIndex);
                  // CollectionChanged event should handle UI updates (like grouping) and stat recalculation signals
                  // OnPropertyChanged(nameof(GroupedRules)); // Likely handled by CollectionChanged listener
                  // NotifyRulesChangedForStats(); // Likely handled by CollectionChanged listener
             } else {
                 Debug.WriteLine($"MoveRule: Source index {sourceIndex} and target index {targetIndex} are the same. No move needed.");
             }

            // Consider if auto-saving rule order or marking dirty state is needed here
        }


        // --- Template Management Logic (Moved and Adapted) ---
        private async Task LoadInitialDataAsync()
        {
             Debug.WriteLine("RulesViewModel: Loading initial data...");
             // Clear existing before loading
             Templates.Clear();
             Rules.Clear(); // Also clear rules initially
             RuleSets.Clear(); // And rule sets

             // Add the special "(所有规则)" option first
             var allRulesTemplate = new LogProcessingTemplate { Name = SpecialTemplateNames.AllRules };
             Templates.Add(allRulesTemplate); 

            try
            {
                var loadedTemplates = await _ruleManagementService.LoadTemplatesAsync();
                // Templates.Clear(); // Already cleared
                foreach (var template in loadedTemplates)
                {
                    Templates.Add(template);
                }
                 Debug.WriteLine($"RulesViewModel: Loaded {Templates.Count - 1} actual templates."); // Adjust count message

                // Set default selection to "All Rules" instead of first real template
                 SelectedTemplate = allRulesTemplate; 
                 // _ = LoadTemplateAsync(SelectedTemplate); // Don't load anything for "All Rules"
                 CurrentTemplateLabel = SpecialTemplateNames.AllRules;
                 // Load default rules only if NO templates were loaded AND file didn't exist initially (or error)
                 // We need a better way to handle initial state vs explicit selection.
                 // Let's load default rules here initially, but allow "All Rules" to show them.
                 LoadDefaultRules(); 

                 // REMOVED: Load Rule Sets
                 // _ = LoadRuleSetsAsync();
            }
            catch (Exception ex)
            {
                 Debug.WriteLine($"RulesViewModel: Error loading initial data: {ex.Message}");
                 LoadDefaultRules(); 
                 CurrentTemplateLabel = SpecialTemplateNames.ErrorFallbackPrefix + ex.Message + "\")";
                 SelectedTemplate = allRulesTemplate; // Fallback selection
            }
             Debug.WriteLine("RulesViewModel: Initial data loading complete.");
             // ADD THIS: Ensure dependent view models are notified AFTER initial load completes.
             NotifyRulesChangedForStats();
        }

        // Helper to load some default rules if templates fail or none exist
        private void LoadDefaultRules()
        {
            Debug.WriteLine("RulesViewModel: Loading default rules...");
            
            foreach (var rule in Rules) { rule.PropertyChanged -= Rule_PropertyChanged; }
            Rules.Clear();

            var defaultRules = new List<RuleItemViewModel> {
               new RuleItemViewModel { Name = "清理时间戳 (HH:MM:SS.ms)", Description = "移除 HH:MM:SS.ms 格式的时间戳", IsEnabled = true, Type = RuleType.RemoveTimestamps },
               new RuleItemViewModel { Name = "清理文件路径 (at ...)", Description = "移除 \"at file.ext:line\" 格式的路径", IsEnabled = false, Type = RuleType.RemoveFilePaths },
               // Add more rules for testing
               new RuleItemViewModel { Name = "排除 DEBUG 日志", Description = "移除包含 '[DEBUG]' 的行", IsEnabled = true, Type = RuleType.FilterExcludes, Keyword = "[DEBUG]" },
               new RuleItemViewModel { Name = "包含 ERROR 日志", Description = "仅保留包含 'ERROR' 的行", IsEnabled = false, Type = RuleType.FilterIncludes, Keyword = "ERROR" },
               new RuleItemViewModel { Name = "替换 Null 为 空字符串", Description = "将 'Null' 替换为空字符串", IsEnabled = true, Type = RuleType.KeywordReplace, Keyword = "Null", Replacement = "" },
               new RuleItemViewModel { Name = "清理 GUID", Description = "移除 GUID 格式的字符串", IsEnabled = true, Type = RuleType.RegexReplace, Keyword = @"""[({]?[a-fA-F0-9]{8}-?([a-fA-F0-9]{4}-?){3}[a-fA-F0-9]{12}[})]""" }, // Example GUID Regex
               new RuleItemViewModel { Name = "另一条排除规则", Description = "移除包含 'TRACE' 的行", IsEnabled = true, Type = RuleType.FilterExcludes, Keyword = "TRACE" },
               new RuleItemViewModel { Name = "替换 IP 地址", Description = "将 IP 地址替换为 '***'", IsEnabled = false, Type = RuleType.RegexReplace, Keyword = @"\b(?:\\d{1,3}\\.){3}\\d{1,3}\b", Replacement = "***" }, // Example IP Regex
            };

            foreach(var ruleVm in defaultRules)
            {
                AssignCommandsToRule(ruleVm); // Assign commands
                ruleVm.PropertyChanged += Rule_PropertyChanged;
                Rules.Add(ruleVm);
            }
            Debug.WriteLine("RulesViewModel: Default rules loaded.");
            Debug.WriteLine($"[RulesViewModel] Rules count after LoadDefaultRules: {Rules.Count}");
        }

        private async Task DeleteSelectedTemplate(object? parameter)
        {
            var templateToDelete = parameter as LogProcessingTemplate ?? SelectedTemplate;
            if (templateToDelete == null) return;

            // Use service to handle confirmation and deletion logic
            bool deleted = await _ruleManagementService.DeleteTemplateAsync(templateToDelete);

            if (deleted)
            {
                var currentSelection = SelectedTemplate; 
                var allRulesItem = Templates.FirstOrDefault(t => t.Name == SpecialTemplateNames.AllRules); // Find the special item
                Templates.Remove(templateToDelete);

                if (currentSelection == templateToDelete)
                {
                    Debug.WriteLine("Deleted selected template. Loading default rules and selecting 'All Rules'.");
                    LoadDefaultRules(); // Explicitly load default rules
                    // Manually set SelectedTemplate without triggering LoadTemplateAsync again
                    _selectedTemplate = allRulesItem; 
                    OnPropertyChanged(nameof(SelectedTemplate)); // Notify UI of selection change
                    CurrentTemplateLabel = SpecialTemplateNames.AllRules; // Update label
                    // GroupedRules and Stats are updated by LoadDefaultRules
                }
                // else: If a different template was deleted, keep the current selection and rules
                 
                Debug.WriteLine($"RulesViewModel: Template '{templateToDelete.Name}' deleted.");
                 await _ruleManagementService.SaveTemplatesAsync(Templates.Where(t => t.Name != SpecialTemplateNames.AllRules));
            }
        }

        private bool CanDeleteTemplate(object? parameter)
        {
            return (parameter as LogProcessingTemplate ?? SelectedTemplate) != null;
        }

        private bool CanExportTemplate()
        {
            // Can export if there are any rules
            return Rules.Any();
        }

        private async Task ExportTemplateAsync()
        {
             if (!CanExportTemplate()) return;

             var jsonFilter = new FilePickerFileType("JSON Files") { Patterns = new[] { "*.json" } };

             var file = await _uiService.ShowSaveFileDialogAsync(
                title: "导出规则模板",
                suggestedFileName: "my-rules.json",
                defaultExtension: "json",
                filters: new List<FilePickerFileType> { jsonFilter }
             );

            if (file is not null)
            {
                try
                {
                    await using var stream = await file.OpenWriteAsync();
                    using var writer = new StreamWriter(stream, System.Text.Encoding.UTF8);
                    var templateData = new LogProcessingTemplate
                    {
                        Name = Path.GetFileNameWithoutExtension(file.Name),
                        Rules = Rules.Select(vm => new RuleDefinition(vm)).ToList()
                    };
                    var options = new JsonSerializerOptions { WriteIndented = true };
                    string json = JsonSerializer.Serialize(templateData, options);
                    await writer.WriteAsync(json);
                    Debug.WriteLine($"[RulesViewModel] Template exported successfully to: {file.Name}");
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"[RulesViewModel] Error exporting template: {ex.Message}");
                    await _uiService.ShowConfirmationDialogAsync("导出失败", $"无法导出模板文件：{ex.Message}");
                }
            }
             else
             {
                 Debug.WriteLine("[RulesViewModel] Export template cancelled by user.");
             }
        }

        // Add ImportTemplateAsync method
        private async Task ImportTemplateAsync()
        {
            var jsonFilter = new FilePickerFileType("JSON Files") { Patterns = new[] { "*.json" } };

            var file = await _uiService.ShowOpenFileDialogAsync(
                title: "导入规则模板",
                filters: new List<FilePickerFileType> { jsonFilter }
            );

            if (file is null)
            {
                Debug.WriteLine("[RulesViewModel] Import template cancelled by user.");
                return;
            }

            try
            {
                await using var stream = await file.OpenReadAsync();
                using var reader = new StreamReader(stream, System.Text.Encoding.UTF8);
                string json = await reader.ReadToEndAsync();

                var loadedTemplate = JsonSerializer.Deserialize<LogProcessingTemplate>(json);

                if (loadedTemplate != null && loadedTemplate.Rules != null)
                {
                    Debug.WriteLine($"[RulesViewModel] Template file parsed: {loadedTemplate.Name} with {loadedTemplate.Rules.Count} rules.");
                    
                    // --- ENHANCEMENT: Ask user if they want to add to list --- 
                    bool addToTemplateList = await _uiService.ShowConfirmationDialogAsync(
                        "添加到列表?",
                        $"要将模板 '{loadedTemplate.Name}' 添加到左侧模板列表吗？"
                        );

                    if (addToTemplateList)
                    {
                        // Handle potential name conflicts
                        string finalTemplateName = loadedTemplate.Name;
                        var existingTemplate = Templates.FirstOrDefault(t => t.Name.Equals(finalTemplateName, StringComparison.OrdinalIgnoreCase));

                        if (existingTemplate != null && existingTemplate.Name != SpecialTemplateNames.AllRules)
                        {
                            bool overwrite = await _uiService.ShowConfirmationDialogAsync(
                                "名称冲突",
                                $"名为 '{finalTemplateName}' 的模板已存在。是否要覆盖它？"
                                );

                            if (overwrite)
                            {
                                Templates.Remove(existingTemplate);
                                Debug.WriteLine($"[RulesViewModel] ImportTemplate: Removed existing template '{finalTemplateName}' for overwrite.");
                            }
                            else
                            {
                                // Option 1: Cancel import to list
                                Debug.WriteLine($"[RulesViewModel] ImportTemplate: Overwrite cancelled for '{finalTemplateName}'. Template not added to list.");
                                // Optionally still load the rules temporarily?
                                // LoadRulesFromTemplateObject(loadedTemplate, true); // Pass flag to indicate temporary load
                                // CurrentTemplateLabel = $"{SpecialTemplateNames.ImportedPrefix}{finalTemplateName} (未保存)";
                                return; // Exit without adding to list or saving

                                // Option 2: Prompt for a new name (more complex UI needed)
                                // string newName = await _uiService.ShowInputDialogAsync(...);
                                // loadedTemplate.Name = newName;
                            }
                        }

                        // Add the new/updated template
                        Templates.Add(loadedTemplate);
                        await _ruleManagementService.SaveTemplatesAsync(Templates.Where(t => t.Name != SpecialTemplateNames.AllRules));
                        Debug.WriteLine($"[RulesViewModel] Template '{loadedTemplate.Name}' added to list and saved.");

                        // Load rules from the newly added template and select it
                        SelectedTemplate = loadedTemplate; // This will trigger LoadTemplateAsync
                        // Ensure LoadTemplateAsync handles loading correctly from the object in Templates

                    }
                    else 
                    { 
                         // User chose not to add to list - Just load the rules temporarily
                        Debug.WriteLine($"[RulesViewModel] User chose not to add '{loadedTemplate.Name}' to list. Loading rules temporarily.");
                        LoadRulesFromTemplateObject(loadedTemplate, true); // Pass flag to indicate temporary
                    }

                    // --- Original logic moved to LoadRulesFromTemplateObject or handled by selecting the template ---
                    /*
                    // Clear existing rules
                    foreach (var ruleVm in Rules.ToList()) 
                    { 
                        ruleVm.PropertyChanged -= Rule_PropertyChanged; 
                        ruleVm.PropertyChanged -= RuleItem_IsSelectedChanged; 
                    }
                    Rules.Clear();

                    // Add rules from the template
                    foreach (var ruleDef in loadedTemplate.Rules)
                    {
                        var ruleVm = ruleDef.ToViewModel();
                        AssignCommandsToRule(ruleVm);
                        ruleVm.PropertyChanged += Rule_PropertyChanged;
                        ruleVm.PropertyChanged += RuleItem_IsSelectedChanged;
                        Rules.Add(ruleVm);
                    }

                    // Update UI state
                    if (isTemporaryLoad)
                    {
                         CurrentTemplateLabel = $"{SpecialTemplateNames.ImportedPrefix}{loadedTemplate.Name} (未保存)";
                         // Do not change SelectedTemplate if temporary
                    }
                    else
                    {
                        CurrentTemplateLabel = loadedTemplate.Name;
                    }
                    
                    OnPropertyChanged(nameof(GroupedRules));
                    NotifyRulesChangedForStats();
                    Debug.WriteLine($"[RulesViewModel] Rules loaded from '{loadedTemplate.Name}'. Count: {Rules.Count}");
                    */
                }
                else
                {
                    Debug.WriteLine("[RulesViewModel] Imported file is not a valid template format.");
                     await _uiService.ShowConfirmationDialogAsync("导入失败", "选择的文件不是有效的规则模板文件。");
                }
            }
            catch (JsonException jsonEx)
            {
                Debug.WriteLine($"[RulesViewModel] Error importing template (JSON parsing): {jsonEx.Message}");
                await _uiService.ShowConfirmationDialogAsync("导入失败", $"无法解析模板文件：{jsonEx.Message}");
            }
            catch (Exception ex)
            {
                Debug.WriteLine($"[RulesViewModel] Error importing template (Other): {ex.Message}");
                 await _uiService.ShowConfirmationDialogAsync("导入失败", $"无法导入模板文件：{ex.Message}");
            }
        }

        // Helper method to load rules from a template object (used by Import and LoadTemplateAsync)
        private void LoadRulesFromTemplateObject(LogProcessingTemplate template, bool isTemporaryLoad = false)
        {
             if (template == null || template.Rules == null) return;

            Debug.WriteLine($"[RulesViewModel] Loading rules from template object: '{template.Name}' (Temporary: {isTemporaryLoad})");

            // Clear existing rules before loading new ones
            foreach (var rule in Rules.ToList()) 
            { 
                rule.PropertyChanged -= Rule_PropertyChanged; 
                rule.PropertyChanged -= RuleItem_IsSelectedChanged; 
            }
            Rules.Clear();

            // Add rules from the template
            foreach (var ruleDef in template.Rules)
            {
                var ruleVm = ruleDef.ToViewModel();
                AssignCommandsToRule(ruleVm);
                ruleVm.PropertyChanged += Rule_PropertyChanged;
                ruleVm.PropertyChanged += RuleItem_IsSelectedChanged;
                Rules.Add(ruleVm);
            }

            // Update UI state
            if (isTemporaryLoad)
            {
                 CurrentTemplateLabel = $"{SpecialTemplateNames.ImportedPrefix}{template.Name} (未保存)";
                 // Do not change SelectedTemplate if temporary
            }
            else
            {
                CurrentTemplateLabel = template.Name;
            }
            
            OnPropertyChanged(nameof(GroupedRules));
            NotifyRulesChangedForStats();
            Debug.WriteLine($"[RulesViewModel] Rules loaded from '{template.Name}'. Count: {Rules.Count}");
        }

        // Renamed: This is triggered by SelectedTemplate setter now
        private async Task LoadTemplateAsync(LogProcessingTemplate? template)
        {
            if (template?.Name == SpecialTemplateNames.AllRules)
            {
                Debug.WriteLine("RulesViewModel: 'All Rules' selected. Displaying current rules.");
                LoadDefaultRules(); 
                CurrentTemplateLabel = SpecialTemplateNames.AllRules;
                return;
            }
            
            if (template == null)
            {
                 Debug.WriteLine("RulesViewModel: LoadTemplateAsync called with null. Loading default rules.");
                 LoadDefaultRules(); 
                 CurrentTemplateLabel = SpecialTemplateNames.NoTemplateFallback;
                 // Manually set SelectedTemplate without triggering LoadTemplateAsync again
                 _selectedTemplate = Templates.FirstOrDefault(t => t.Name == SpecialTemplateNames.AllRules); 
                 OnPropertyChanged(nameof(SelectedTemplate)); 
                 // GroupedRules and Stats updated by LoadDefaultRules
                 return;
            }

            Debug.WriteLine($"RulesViewModel: Loading template: {template.Name}");

            // Standard template loading logic...
            foreach (var rule in Rules) 
            { 
                rule.PropertyChanged -= Rule_PropertyChanged; 
                rule.PropertyChanged -= RuleItem_IsSelectedChanged; 
            }
            Rules.Clear();
            SelectedRules.Clear();

            try
            {
                // Now directly use the template object passed in, assuming it has rules if it's not null
                // The service call might still be needed if templates are stored elsewhere and not fully loaded in memory
                // Let's assume the Template object in the collection already has its rules loaded
                // If _ruleManagementService.LoadTemplatesAsync() only loads names, we need to load rules here.
                
                // Option A: Assume template object from Templates collection has rules pre-loaded
                if (template.Rules == null || !template.Rules.Any())
                {
                    // Maybe rules need to be loaded on demand?
                    Debug.WriteLine($"Warning: Template '{template.Name}' selected, but Rules collection is null or empty. Attempting to load from service.");
                    var rules = await _ruleManagementService.LoadRulesFromTemplateAsync(template);
                    template.Rules = rules.Select(vm => new RuleDefinition(vm)).ToList(); // Populate rules in the template object
                }

                LoadRulesFromTemplateObject(template); // Load rules into the Rules collection

                // Option B: Always fetch rules from service when template is selected
                // var loadedRuleVMs = await _ruleManagementService.LoadRulesFromTemplateAsync(template);
                // LoadRulesFromVMs(loadedRuleVMs); // Need another helper or integrate into LoadRulesFromTemplateObject

                // CurrentTemplateLabel = template.Name; // Handled by LoadRulesFromTemplateObject
                 Debug.WriteLine("RulesViewModel: Template loaded successfully.");
            }
            catch (Exception ex)
            {
                 Debug.WriteLine($"RulesViewModel: Error loading template '{template.Name}': {ex.Message}");
                 LoadDefaultRules(); // Load defaults on error
                 CurrentTemplateLabel = $"{SpecialTemplateNames.ErrorFallbackPrefix}{template.Name})";
            }
            // Trigger UI updates after loading
            OnPropertyChanged(nameof(GroupedRules));
            NotifyRulesChangedForStats();
        }

         // --- Rule Creation from Selection Logic (Moved and Adapted) ---
         private async Task CreateRuleFromSelection()
         {
            Debug.WriteLine("[RulesViewModel] CreateRuleFromSelection command execution started.");
             // Read selected text from LogPanelViewModel
             string? selection = _logPanelViewModel.SelectedOriginalLogText;
             Debug.WriteLine($"[RulesViewModel] CreateRuleFromSelection executed. Selection from LogPanelVM: '{selection ?? "null"}'");

             if (string.IsNullOrWhiteSpace(selection))
             {
                 Debug.WriteLine("CreateRuleFromSelection: Selection is null or whitespace (from LogPanelVM).");
                 return;
             }

             // Reverted: Logic to create rule/editor VM locally
             string trimmedSelection = selection.Trim();
             string selectionSnippet = trimmedSelection.Substring(0, Math.Min(trimmedSelection.Length, 20));
             string ellipsis = trimmedSelection.Length > 20 ? "..." : "";
             string ruleName = $"排除 '{selectionSnippet}{ellipsis}'";
             string description = $"移除包含 \"{trimmedSelection}\" 的行";

             var tempRule = new RuleItemViewModel
             {
                 Name = ruleName,
                 Description = description,
                 Type = RuleType.FilterExcludes,
                 Keyword = trimmedSelection,
                 IsEnabled = true
             };

             var editorVm = new RuleEditorViewModel(tempRule); 

             var newRule = await _uiService.ShowRuleEditorDialogAsync(editorVm);
             Debug.WriteLine($"[RulesViewModel] ShowRuleEditorDialogAsync returned: {(newRule == null ? "null" : newRule.Name)}");

             if (newRule != null)
             {
                 AssignCommandsToRule(newRule);
                 newRule.PropertyChanged += Rule_PropertyChanged;
                 Rules.Add(newRule);
                 Debug.WriteLine($"New rule added from selection: {newRule.Name}");
             }
             else
             {
                 Debug.WriteLine("Rule creation from selection cancelled or failed in service.");
             }
         }

        // --- Grouped Rules for UI (Moved) ---
        private IEnumerable<RuleGroup> GenerateGroupedRules()
        {
            return Rules
                .GroupBy(rule => rule.Type) // Group by RuleType
                .OrderBy(group => GetRuleTypeSortOrder(group.Key)) // Order groups logically
                .Select(group => new RuleGroup(GetRuleTypeDisplayName(group.Key), group.ToList())) // Map to RuleGroup
                .ToList(); // Convert to List for binding stability
        }

        // Helper to get display name for RuleType (Moved)
        private string GetRuleTypeDisplayName(RuleType type)
        {
             return type switch
             {
                 RuleType.FilterIncludes => "包含规则 (FilterIncludes)",
                 RuleType.FilterExcludes => "排除规则 (FilterExcludes)",
                 RuleType.KeywordReplace => "关键词替换 (KeywordReplace)",
                 RuleType.RegexReplace => "正则替换 (RegexReplace)",
                 RuleType.RemoveTimestamps => "移除时间戳 (RemoveTimestamps)",
                 RuleType.RemoveFilePaths => "移除文件路径 (RemoveFilePaths)",
                 _ => $"{type} (未知类型)" // Default case, ensuring English name is also included
             };
        }

        // Helper to get sort order for RuleType (Moved)
        private int GetRuleTypeSortOrder(RuleType type)
        {
             return type switch
             {
                 RuleType.FilterIncludes => 1,
                 RuleType.FilterExcludes => 2,
                 RuleType.KeywordReplace => 3,
                 RuleType.RegexReplace => 4,
                 RuleType.RemoveTimestamps => 5,
                 RuleType.RemoveFilePaths => 6,
                 _ => 99 // Default case
             };
        }

        // --- NEW: Create Template From Selection ---
        private async Task CreateTemplateFromSelectionAsync()
        {
            var selectedRules = Rules.Where(r => r.IsSelected).ToList();
            if (!selectedRules.Any())
            {
                Debug.WriteLine("[RulesViewModel] CreateTemplateFromSelection: No rules selected.");
                // Optionally show message to user via UI service
                await _uiService.ShowConfirmationDialogAsync("无法创建", "请先勾选至少一个规则。");
                return;
            }

            string? templateName = await _uiService.ShowInputDialogAsync("创建规则模板", "请输入新模板的名称:");

            if (!string.IsNullOrWhiteSpace(templateName))
            {
                templateName = templateName.Trim(); // Trim whitespace

                // Check for duplicate name
                if (Templates.Any(t => t.Name.Equals(templateName, StringComparison.OrdinalIgnoreCase)))
                {
                    bool overwrite = await _uiService.ShowConfirmationDialogAsync(
                        "名称冲突",
                        $"名为 '{templateName}' 的模板已存在。是否要覆盖它？"
                        );

                    if (!overwrite)
                    {
                         Debug.WriteLine($"[RulesViewModel] CreateTemplateFromSelection: Overwrite cancelled for '{templateName}'.");
                         return; // User chose not to overwrite
                    }
                    // Remove existing template if overwriting
                    var existingTemplate = Templates.FirstOrDefault(t => t.Name.Equals(templateName, StringComparison.OrdinalIgnoreCase));
                    if (existingTemplate != null)
                    {
                        Templates.Remove(existingTemplate);
                        Debug.WriteLine($"[RulesViewModel] CreateTemplateFromSelection: Removed existing template '{templateName}' for overwrite.");
                    }
                }

                var newTemplate = new LogProcessingTemplate
                {
                    Name = templateName,
                    Rules = selectedRules.Select(vm => new RuleDefinition(vm)).ToList()
                };

                Templates.Add(newTemplate);
                Debug.WriteLine($"[RulesViewModel] Template '{newTemplate.Name}' created with {newTemplate.Rules.Count} rules.");

                // Save Templates after adding/overwriting
                try
                {
                     // Filter out the special "All Rules" template before saving
                     await _ruleManagementService.SaveTemplatesAsync(Templates.Where(t => t.Name != SpecialTemplateNames.AllRules));
                     Debug.WriteLine("[RulesViewModel] Templates saved after creation.");

                    // Deselect rules after successful creation and save
                    foreach (var rule in selectedRules)
                    {
                        rule.IsSelected = false;
                    }
                    // Notify command CanExecute might have changed after deselecting
                    (CreateTemplateFromSelectionCommand as IAsyncRelayCommand)?.NotifyCanExecuteChanged(); 

                    // Optionally select the newly created template
                    SelectedTemplate = newTemplate;

                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"[RulesViewModel] Error saving templates after creation: {ex.Message}");
                    // Handle error - maybe remove the template added in memory? Or inform user.
                    Templates.Remove(newTemplate); // Rollback add
                    await _uiService.ShowConfirmationDialogAsync("保存失败", $"无法保存新创建的模板 '{templateName}': {ex.Message}");
                }
            }
            else
            {
                Debug.WriteLine("[RulesViewModel] Create Template From Selection cancelled or name was empty.");
            }
        }

        private bool CanCreateTemplateFromSelection()
        {
            // Can create if at least one rule is selected
            bool canExecute = Rules.Any(r => r.IsSelected);
            // Debug.WriteLine($"[RulesViewModel] CanCreateTemplateFromSelection: {canExecute}");
            return canExecute;
        }

        // ... other methods ...

        // Handler for LogPanelVm's event
        private void LogPanelVm_SelectedOriginalLogTextChanged(object? sender, EventArgs e)
        {
            // Notify command that its CanExecute status might have changed
            (CreateRuleFromSelectionCommand as IAsyncRelayCommand)?.NotifyCanExecuteChanged();
        }

        private bool CanCreateRuleFromSelection()
        {
            bool canExecute = !string.IsNullOrEmpty(_logPanelViewModel.SelectedOriginalLogText);
            // Debug.WriteLine($"[RulesViewModel] CanCreateRuleFromSelection called. Result: {canExecute}"); // Optional debug log
            return canExecute;
        }

        // --- Batch Template Operations ---

        private async Task ExportAllTemplatesAsync()
        {
            Debug.WriteLine("[RulesViewModel] ExportAllTemplates command executed.");
            await _uiService.ShowConfirmationDialogAsync("功能暂未实现", "批量导出功能当前不可用 (缺少 ShowFolderPickerAsync)。");
            /* // Temporarily disable logic due to missing ShowFolderPickerAsync
            var templatesToExport = Templates.Where(t => t.Name != SpecialTemplateNames.AllRules).ToList();

            if (!templatesToExport.Any())
            {
                 await _uiService.ShowConfirmationDialogAsync("无模板", "没有可导出的模板。");
                 return;
            }

            // Assume IUIService has ShowFolderPickerAsync
            var targetFolder = await _uiService.ShowFolderPickerAsync("选择导出文件夹");

            if (targetFolder is null)
            {
                Debug.WriteLine("[RulesViewModel] ExportAllTemplates cancelled by user.");
                return;
            }

            int successCount = 0;
            int errorCount = 0;
            var options = new JsonSerializerOptions { WriteIndented = true };

            foreach (var template in templatesToExport)
            {
                // Sanitize filename (simple example, might need more robust sanitization)
                string fileName = string.Join("_", template.Name.Split(Path.GetInvalidFileNameChars())) + ".json";
                // Avalonia's IStorageFolder interface is needed here.
                // Assuming targetFolder has a way to create/get a file stream, e.g., targetFolder.CreateFileAsync(fileName) or similar
                // This depends heavily on the actual implementation of IUIService and IStorageFolder
                try
                {
                    // Placeholder: Needs actual Avalonia Storage API usage 
                    var file = await targetFolder.CreateFileAsync(fileName); // Hypothetical method
                    if (file != null)
                    {
                        await using var stream = await file.OpenWriteAsync();
                        using var writer = new StreamWriter(stream, System.Text.Encoding.UTF8);
                        string json = JsonSerializer.Serialize(template, options);
                        await writer.WriteAsync(json);
                        successCount++;
                    }
                    else
                    {
                        Debug.WriteLine($"[RulesViewModel] ExportAllTemplates: Failed to create file '{fileName}' in target folder.");
                        errorCount++;
                    }
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"[RulesViewModel] ExportAllTemplates: Error exporting template '{template.Name}' to '{fileName}': {ex.Message}");
                    errorCount++;
                }
            }

            // Show summary message
            string summaryMessage = $"导出完成。成功: {successCount}, 失败: {errorCount}.";
            if(errorCount > 0) summaryMessage += "\n请检查日志获取详细错误信息。";
            await _uiService.ShowConfirmationDialogAsync("批量导出结果", summaryMessage);
            Debug.WriteLine($"[RulesViewModel] ExportAllTemplates finished. Success: {successCount}, Errors: {errorCount}");
            */
        }

        private async Task ImportTemplatesFromFolderAsync()
        {
            Debug.WriteLine("[RulesViewModel] ImportTemplatesFromFolder command executed.");
            await _uiService.ShowConfirmationDialogAsync("功能暂未实现", "批量导入功能当前不可用 (缺少 ShowFolderPickerAsync)。");
            /* // Temporarily disable logic due to missing ShowFolderPickerAsync

            var sourceFolder = await _uiService.ShowFolderPickerAsync("选择包含模板的文件夹");

            if (sourceFolder is null)
            {
                Debug.WriteLine("[RulesViewModel] ImportTemplatesFromFolder cancelled by user.");
                return;
            }

            int successCount = 0;
            int errorCount = 0;
            var importedTemplates = new List<LogProcessingTemplate>();
            List<string> failedFiles = new List<string>();

            // Again, depends on IStorageFolder interface. Assuming GetFilesAsync or similar.
            var files = await sourceFolder.GetFilesAsync(); // Hypothetical method, might need pattern matching e.g., GetFilesAsync("*.json")

            foreach (var file in files.Where(f => f.Name.EndsWith(".json", StringComparison.OrdinalIgnoreCase)))
            {
                try
                {
                    await using var stream = await file.OpenReadAsync();
                    using var reader = new StreamReader(stream, System.Text.Encoding.UTF8);
                    string json = await reader.ReadToEndAsync();
                    var loadedTemplate = JsonSerializer.Deserialize<LogProcessingTemplate>(json);

                    if (loadedTemplate != null && !string.IsNullOrWhiteSpace(loadedTemplate.Name) && loadedTemplate.Rules != null)
                    {
                        importedTemplates.Add(loadedTemplate);
                        successCount++;
                    }
                    else
                    { 
                        Debug.WriteLine($"[RulesViewModel] ImportTemplatesFromFolder: File '{file.Name}' is not a valid template or has missing data.");
                        errorCount++;
                        failedFiles.Add(file.Name);
                    }
                }
                 catch (JsonException jsonEx)
                {
                    Debug.WriteLine($"[RulesViewModel] ImportTemplatesFromFolder: Error parsing JSON in file '{file.Name}': {jsonEx.Message}");
                    errorCount++;
                    failedFiles.Add(file.Name);
                }
                catch (Exception ex)
                {
                    Debug.WriteLine($"[RulesViewModel] ImportTemplatesFromFolder: Error reading file '{file.Name}': {ex.Message}");
                    errorCount++;
                    failedFiles.Add(file.Name);
                }
            }

            if (!importedTemplates.Any())
            {
                await _uiService.ShowConfirmationDialogAsync("未找到模板", $"在所选文件夹中未找到有效的模板文件。失败: {errorCount}");
                return;
            }

            // Add imported templates to the main list, handling duplicates
            int addedCount = 0;
            int skippedCount = 0;
            foreach (var importedTemplate in importedTemplates)
            {
                var existing = Templates.FirstOrDefault(t => t.Name.Equals(importedTemplate.Name, StringComparison.OrdinalIgnoreCase));
                if (existing == null)
                {
                    Templates.Add(importedTemplate);
                    addedCount++;
                }
                else
                {
                    // Simple strategy: Skip duplicates
                    // Could enhance to ask user per duplicate or have an overall strategy (skip/overwrite)
                    Debug.WriteLine($"[RulesViewModel] ImportTemplatesFromFolder: Skipping duplicate template name '{importedTemplate.Name}'.");
                    skippedCount++;
                }
            }

            if (addedCount > 0)
            {
                 // Save if any templates were actually added
                try
                {
                    await _ruleManagementService.SaveTemplatesAsync(Templates.Where(t => t.Name != SpecialTemplateNames.AllRules));
                    Debug.WriteLine($"[RulesViewModel] Templates saved after batch import.");
                }
                 catch (Exception ex)
                {
                    Debug.WriteLine($"[RulesViewModel] Error saving templates after batch import: {ex.Message}");
                    // Consider how to inform the user - templates are in memory but not saved
                     await _uiService.ShowConfirmationDialogAsync("保存失败", $"导入的部分模板已加载，但保存模板列表时出错: {ex.Message}");
                     // Maybe rollback the adds? (more complex)
                }
            }

            // Show summary message
             string summaryMessage = $"批量导入完成。成功解析: {successCount}, 新增: {addedCount}, 跳过重复: {skippedCount}, 解析失败: {errorCount}.";
            if(failedFiles.Any())
            {
                summaryMessage += "\n以下文件解析失败: " + string.Join(", ", failedFiles.Take(5)); // Show first few failed files
                if(failedFiles.Count > 5) summaryMessage += "...";
            }
            await _uiService.ShowConfirmationDialogAsync("批量导入结果", summaryMessage);
            Debug.WriteLine($"[RulesViewModel] ImportTemplatesFromFolder finished. Parsed: {successCount}, Added: {addedCount}, Skipped: {skippedCount}, Errors: {errorCount}");

            */
        }
    }
} 